<script lang="ts" setup>
import type { ProducerType, SceneIntroductionType } from '@/types/micro-scene';
import { CheckOutlined, CloseOutlined, EditOutlined, ShareAltOutlined, UserOutlined } from '@ant-design/icons-vue';
import { computed, onMounted, ref, watch } from 'vue';
import frontIcon from "@/assets/front/front2.png";
import { useUserStore } from '@/stores/useUserStore';
import { debounce } from 'lodash';
import { getMicroScenePublishStatus, getSceneOverviewDetail, searchUser, updateMicroScenePublishStatus, updateSceneOverviewDetail } from '@/api/MicroScene/MicroSceneDetailApi';
import { useRoute } from 'vue-router';
const route = useRoute();
const userStore = useUserStore()
const sceneIntroduction = ref<SceneIntroductionType>({
  title: '基于多模态大模型的图像伪造检测与定位',
  producer: [
    {
      name: '鄂海红',
      college: '北京邮电大学计算机学院',
      schoolId: '001',
      avatar: '',
      uid: '001',
    },
  ],
  description: '随着图像编辑技术和大模型技术的迅猛发展，一些学者为了迎合期刊审稿人或提升自己研究的可信度，使用图像生成/补全技术伪造学术图像。模型生成的伪造图像通常无法被审稿人和编辑用肉眼来判别，且传统的图像篡改检测技术难以应对模型生成的图像，检测准确率较低，难以有效识别和定位图像中的伪造区域。此外，当前图像伪造方法多样且使用工具繁多，使得图像伪造的检测与定位任务异常艰难。\n 为应对上述问题，本项目提出了基于多模态大模型的图像伪造监测与定位。首先基于PubMed论文库获取学术图像，通过"文生图"模型生成大量且多样不同伪造目的的伪造图像构建科研领域特定的图文匹配对数据集，接下来使用数据集对多模态大模型进行微调，从而有效提升模型对科研图像伪造检测与定位的准确率与可解释性，最后完成模型的评测与模型服务部署，为学术展示和项目推广提供支持。',
})

// 获取任务详情
const fetchSceneOverviewDetail = async () => {
  try {
    // 从路由中获取微场景id
    const microSceneId = route.params.id as string;
    const response = await getSceneOverviewDetail(microSceneId);
    sceneIntroduction.value.title = response.sceneTitle;
    sceneIntroduction.value.description = response.introduction;

    // 设置出品人信息
    sceneIntroduction.value.producer = response.authors.map((author: any) => ({
      // 作者姓名
      name: author.realname,
      // 学校名称+学院名称(都可能为空)
      college: (author.schoolName || '') + (author.userCollege || ''),
      // 作者id
      schoolId: author.schoolId,
      // 头像
      avatar: author.userImage,
      // 用户id
      uid: author.userId,
    }));
  }
  catch (error) {
    console.error('获取任务详情失败:', error);
  }
};

// 对标题进行缓存，方便恢复
const titleCache = ref<string>('')

// 对描述进行缓存，方便恢复
const descriptionCache = ref<string>('')

// 对出品人进行缓存，方便恢复
const producerCache = ref<ProducerType[]>([])

// 是否处于编辑状态
const isEdit = ref(false)

const showEdit = computed(() => {
  return userStore.isEditMicroScene
})

// 出品人选择器状态
const producerState = ref({
  data: [] as { label: string; value: string; info: ProducerType }[], // 添加 info 字段
  fetching: false,
  // note: a-select 的 value 是只能是 number 或者 string 不能自定义类型
  value: [] as { label: string; value: string; }[], // value 只保留 id
})

const handleEdit = () => {
  isEdit.value = true
  // 缓存数据
  titleCache.value = sceneIntroduction.value.title
  descriptionCache.value = sceneIntroduction.value.description

  // 初始化选择器的值，同时构建完整的 option 对象
  const initialData = sceneIntroduction.value.producer.map(item => ({
    label: `${item.name} ${item.schoolId}`,
    value: item.schoolId,
    info: item,
  }))

  // 设置初始数据
  producerState.value.data = initialData
  // eslint-disable-next-line no-console
  console.log('initialData', producerState.value.data)

  // 设置初始选中值
  producerState.value.value = initialData.map(item => ({
    label: item.label,
    value: item.value,
    key: item.value,
  }))
  // 初始化缓存数据
  producerCache.value = initialData.map(item => item.info)
}

const handleSave = async () => {
  isEdit.value = false
  // 覆盖数据
  sceneIntroduction.value.title = titleCache.value
  sceneIntroduction.value.description = descriptionCache.value
  sceneIntroduction.value.producer = producerCache.value

  const userList = sceneIntroduction.value.producer.map(item => item.uid)

  try {
    // 更新微场景详情
    await updateSceneOverviewDetail(route.params.id as string, sceneIntroduction.value.title, sceneIntroduction.value.description, userList)
    // 更新用户关于这个微场景的权限
    userStore.setIsMicroScenePermission(route.params.id as string);
  }
  catch (error) {
    await fetchSceneOverviewDetail();
    console.error("更新微场景详情失败", error);
    throw new Error("更新微场景详情失败");
  }
}

const handleCancel = () => {
  isEdit.value = false
  // 清理缓存
  titleCache.value = ''
  descriptionCache.value = ''
  producerCache.value = []
  // 清理选择器状态
  producerState.value.value = []
  producerState.value.data = []
  producerState.value.fetching = false
}

// 防止重复请求，记录请求ID号
let lastFetchId = 0;
// 获取出品人，默认输入的是学号或者姓名
const fetchProducer = debounce((value: string) => {
  lastFetchId += 1
  const fetchId = lastFetchId
  producerState.value.fetching = true

  setTimeout(async () => {
    // 如果请求ID不一致，说明有新的请求，直接返回
    if (fetchId !== lastFetchId)
      return;
    // 处理数据，将返回数据变为 label-value 格式
    const userList = await searchUser(value)

    // 将用户数据列表整理成需要的格式
    const data = userList.map((item: any) => ({
      label: `${item.realname} ${item.schoolId}`,
      value: item.schoolId,
      info: {
        name: item.realname,
        college: (item.schoolName || '') + (item.userCollege || ''),
        schoolId: item.schoolId,
        uid: item.userId,
        avatar: item.userImage,
      }, // 将完整的 ProducerType 对象放在 info 中
    }))
    // 不能直接覆盖，否则会丢失 option 字段，应该保留已经选中的字段，这个也需要在候选集中，然后去重
    const selectedLabel = producerState.value.value.map(item => item.label)
    // 获取原来以及选中的
    const selectedData = producerState.value.data.filter(item => selectedLabel.includes(item.label))
    // 去除label已经存在的
    const uniqueData = data.filter((item: any) => !selectedLabel.includes(item.label))
    // 追加数组
    producerState.value.data = [...selectedData, ...uniqueData]
    producerState.value.fetching = false
  }, 300)
}, 300)

// 添加选择变化的处理函数
const handleSelect = (selectedOptions: { label: string; value: string; option: any }[]) => {
  producerState.value.value = selectedOptions
  // eslint-disable-next-line no-console
  console.log('producerState.value.data', producerState.value.data)

  // 根据选中的 id 找到对应的完整信息
  const selectedProducers = selectedOptions.map((option) => {
    // 从 data 中查找
    const matchedOption = producerState.value.data.find(item => item.label === option.label)
    return matchedOption?.info
  }).filter((item): item is ProducerType => item !== undefined)

  // eslint-disable-next-line no-console
  console.log('selectedProducers', selectedProducers)

  // 更新缓存
  producerCache.value = selectedProducers
}

// 微场景的发布状态
const microScenePublishStatus = ref(false)
// 更改微场景的发布状态
const handlePublishMicroScene = async () => {
  microScenePublishStatus.value = await updateMicroScenePublishStatus(route.params.id as string)
}

// 获取微场景的发布状态
const fetchMicroScenePublishStatus = async () => {
  microScenePublishStatus.value = await getMicroScenePublishStatus(route.params.id as string)
}

onMounted(() => {
  fetchMicroScenePublishStatus();
  fetchSceneOverviewDetail();
})
</script>

<template>
  <div class="">
    <div class="flex gap-8 items-center">
      <!-- 标题编辑区域 -->
      <div>
        <h1 v-show="!isEdit" class="text-4xl font-bold">
          {{ sceneIntroduction.title }}
        </h1>
        <a-input v-show="isEdit" v-model:value="titleCache" class="w-[25rem]" />
      </div>
      <a-space v-if="showEdit">
        <a-button v-show="!isEdit" type="primary" @click="handleEdit">
          编辑
          <template #icon>
            <EditOutlined />
          </template>
        </a-button>
        <a-switch v-show="!isEdit" v-model:checked="microScenePublishStatus" class="ml-4" @change="handlePublishMicroScene" />
        <div v-if="!isEdit">
          <div v-if="microScenePublishStatus" class="text-sm text-gray-500">
            微场景已发布
          </div>
          <div v-else class="text-sm text-gray-500">
            微场景尚未发布
          </div>
        </div>
        <a-button v-show="isEdit" @click="handleCancel">
          <template #icon>
            <CloseOutlined />
          </template>
        </a-button>
        <a-button v-show="isEdit" type="primary" @click="handleSave">
          <template #icon>
            <CheckOutlined />
          </template>
        </a-button>
      </a-space>
    </div>
    <div class="flex items-center justify-start w-full">
      <img :src="frontIcon" alt="frontIcon" class="w-3 h-3 flex-shrink-0">
      <div v-if="!isEdit" class="text-sm text-gray-500 ml-2 truncate w-full gap-2 flex items-center">
        <span>出品人：</span>
        <a-space v-for="item in sceneIntroduction.producer" :key="item.schoolId" class="text-sm">
          <a-avatar size="small" :src="item.avatar" />
          <span>
            {{ item.college }} {{ item.name }}
          </span>
        </a-space>
      </div>
      <a-select
        v-else v-model:value="producerState.value" style="width: 100%" mode="multiple" label-in-value
        :options="producerState.data" placeholder="输入学工号或姓名选择出品人" :filter-option="false"
        :not-found-content="producerState.fetching ? undefined : null" @search="fetchProducer" @change="handleSelect"
      >
        <template v-if="producerState.fetching" #notFoundContent>
          <a-spin size="small" />
        </template>
      </a-select>
    </div>
    <!-- 介绍区域编辑 -->
    <div class="mt-2">
      <div v-show="!isEdit" class="text-sm whitespace-pre-wrap">
        {{ sceneIntroduction.description }}
      </div>
      <a-textarea
        v-show="isEdit" v-model:value="descriptionCache" :auto-size="{ minRows: 3, maxRows: 10 }"
        class="w-full"
      />
    </div>
  </div>
</template>

<style lang="scss" scoped>
.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
</style>
